#!/bin/bash

## Author: congyang
## Time: 2020/10/15
## Version: 1.1
## Description: system initialization

if [ `id -u` != 0 ]; then
    echo -e "\033[43;30mPermission denied ! Please use root user\033[0m"
    exit 1
fi

## 修改阿里云repo
function change_repo() {
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-$1.repo
    sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
    yum makecache
}

## 修改系统参数
function system_init() {
    local timestamp=`date +%F-%T`
    mv /etc/sysctl.conf /etc/sysctl.conf.bak-$timestamp
    cat > /etc/sysctl.conf << EOF
# 关闭 ipv6 
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

# 开启反向路径过滤
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

#处理无源路由的包
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# 关闭路由转发
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# 确保无人能修改路由表
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0

# 内核放弃建立连接之前发送SYNACK/SYN包的数量
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1

# 允许将TIME-WAIT sockets重新用于新的TCP 连接
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000

net.ipv4.tcp_fin_timeout = 30           # 设置TCP三次请求的fin状态超时
net.ipv4.tcp_keepalive_time = 600       # 设置TCP发送keepalive的频度
net.ipv4.tcp_syncookies = 1             # 加强对抗SYN Flood的能力
net.ipv4.tcp_keepalive_intvl = 2        # 探测包发送时间的间隔设置
net.ipv4.tcp_keepalive_probes = 2       # 客户端无应答，探测包的发送次数
net.ipv4.tcp_max_tw_buckets = 55000     # 系统同时保持time-wait的最大数量
net.ipv4.tcp_rmem = 4096 87380 4194304  # 接受数据缓冲区范围
net.ipv4.tcp_wmem = 4096 16384 4194304  # 发送数据缓冲区范围
net.ipv4.tcp_retries2 = 5               # TCP失败重传次数
net.ipv4.ip_local_port_range = 1100 65000       # 允许系统打开的端口范围
net.ipv4.tcp_max_orphans = 3276800              # 防止简单的DoS 攻击
net.ipv4.tcp_max_syn_backlog = 262144           # 表示SYN队列的长度
net.ipv4.icmp_echo_ignore_broadcasts = 1        # 避免放大攻击
net.ipv4.icmp_ignore_bogus_error_responses = 1  # 开启恶意icmp错误消息保护
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.all.arp_announce=2
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1

net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 65535 # 系统同时发起的tcp连接数

net.netfilter.nf_conntrack_max=655350                    # 修改防火墙表大小
net.netfilter.nf_conntrack_tcp_timeout_established = 300 # 设置tcp确认超时时间
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 12    # 设置tcp等待时间
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60   # 设置tcp关闭等待时间
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120    # 设置tcp fin状态的超时时间

kernel.shmmax = 68719476736 #用户postfix邮件服务器
kernel.shmall = 4294967296
kernel.sysrq = 0            # 关闭sysrq功能
kernel.pid_max = 65536      # 允许更多的PIDs
kernel.core_uses_pid = 1    # core文件名中添加pid作为扩展名
kernel.msgmnb = 65536       # 修改消息队列长度
kernel.msgmax = 65536

fs.file-max = 65535         # 增加系统文件描述符限制
vm.swappiness = 0
vm.max_map_count = 262144
EOF

    mv /etc/security/limits.conf /etc/security/limits.conf.bak-$timestamp
    cat >> /etc/security/limits.conf << EOF
# noproc 是代表最大进程数
# nofile 是代最大文件打开数
root hard nofile 65535
root soft nofile 65535
* soft nofile 65535
* hard nofile 65535
* soft nproc 65535
* hard nproc 65535
* - nofile 65535
EOF

    echo "DefaultLimitNOFILE=65535" >> /etc/systemd/system.conf

    mv /etc/security/limits.d/20-nproc.conf /etc/security/limits.d/20-nproc.conf.bak-$timestamp
    echo -e "*          soft    nproc     40960\nroot       soft    nproc     unlimited" >> /etc/security/limits.d/20-nproc.conf

    ulimit -n 65535
    sysctl -p && systemctl daemon-reload
}

## 关闭firewalld
function stop_firewalld() {
    systemctl stop firewalld.service
    systemctl disable firewalld.service
}

## 关闭selinux
function disable_selinux() {
    setenforce 0
    sed -i s"/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
}

## 关闭swap
function disable_swap() {
    swapoff -a   && sed -i 's/.*swap.*/#&/' /etc/fstab
}

## 修改ssh配置
function change_ssh(){
    local timestamp=`date +%F-%T`
    mv /etc/ssh/sshd_config /etc/ssh/sshd_config-$timestamp
    cat > /etc/ssh/sshd_config << EOF
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
AuthorizedKeysFile      .ssh/authorized_keys
HostbasedAuthentication no
IgnoreRhosts yes
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
X11Forwarding yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
Subsystem       sftp    /usr/libexec/openssh/sftp-server

PermitEmptyPasswords no
UsePAM yes
UseDNS no
PermitRootLogin yes
EOF
    systemctl restart sshd.service
}

## 修改sudoers配置,开启wheel组
function change_sudoers() {
    setenforce 0
    sed -i "s@#%wheel ALL=(ALL)       ALL@%wheel ALL=(ALL)       ALL@g" /etc/sudoers
}

## 安装必备软件
function soft_install() {
    yum install -y gcc openssl openssl-devel perl perl-devel wget unzip \
                    pcre-devel ntpdate ntp sysstat lrzsz vim snmp git \
                    epel-release net-tools lsof traceroute bind-utils
}

## 开启ntpd 修改时区
function start_ntpd() {
    systemctl start ntpd
    systemctl enable ntpd
    timedatectl set-timezone Asia/Shanghai
    echo "0 0 * * * /usr/sbin/ntpdate ntp.api.bz > /dev/null 2>&1" >> /etc/crontab
    ntpdate time1.aliyun.com
}

## 安装docker
function docker_install() {
    yum remove -y docker docker-client docker-client-latest docker-common \
                  docker-latest docker-latest-logrotate docker-logrotate \
                  docker-engine
    
    yum install -y yum-utils device-mapper-persistent-data lvm2 
    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    sleep 3
    yum install -y docker-ce docker-ce-cli containerd.io
    local etc_docker=/etc/docker
    [ ! -d $etc_docker ] && mkdir -p $etc_docker
    echo '{"storage-driver": "overlay2", "graph":"/opt/docker/data", "storage-opts": ["overlay2.override_kernel_check=true"], "log-opts":{ "max-size": "200m","max-file": "5"}}' > /etc/docker/daemon.json
    sed -ri s"#ExecStart=(.*)#ExecStart=\1 -H tcp://0.0.0.0:2375#" /usr/lib/systemd/system/docker.service
    systemctl daemon-reload
    systemctl restart docker
    systemctl enable docker
    echo "Docker Root Dir和Storage Driver已修改"
}

function main(){
    #myos=`cat /etc/redhat-release | grep -w "CentOS" | wc -l`
    #if [ $myos -eq 1 ];then
    #    local ver=`uname -r | awk -F '.' '{print $4}' | cut -b 3`
    #    change_repo $ver
    #fi
    system_init
    stop_firewalld
    disable_selinux
    disable_swap
    change_ssh
    change_sudoers
    soft_install
    start_ntpd
    read -p "安装docker请输入1, 其他输入不安装: " flag
    if [ $flag -eq 1 ]; then
        docker_install
    else
        echo "跳过安装docker..."
    fi

    echo "----------系统初始化成功----------"
}

main
